<?php
namespace App\Common\Lib\Api;

use App\Common as com;

class Response extends com\Lib\LibBase {

	/**
	 * @var int
	 */
	private int $code = 0;

	/**
	 * @var string
	 */
	private string $msg = '';

	/**
	 * @var array
	 */
	private array $data = [];

	/**
	 * @var array
	 */
	private array $extendedData = [];

	/**
	 * @return com\Lib\Api\Response\TypeObj
	 */
	public function getApiResponse():com\Lib\Api\Response\TypeObj {
		return self::common( $this->getCode(), $this->getMsg(), $this->getData(), $this->getExtendedData() );
	}

	/**
	 * 获取code
	 * @return int
	 */
	public function isSuccessStatus():int {
		return $this->code === 1;
	}

	/**
	 * 获取code
	 * @return int
	 */
	public function getCode():int {
		return $this->code;
	}

	/**
	 * 设置code
	 * @param int $code
	 * @return static
	 */
	public function setCode( int $code ):static {
		$this->code = $code;
		//
		return $this;
	}

	/**
	 * 获取msg
	 * @return string
	 */
	public function getMsg():string {
		return $this->msg;
	}

	/**
	 * 设置msg
	 * @param string $msg
	 * @return static
	 */
	public function setMsg( string $msg ):static {
		$this->msg = $msg;
		//
		return $this;
	}

	/**
	 * 设置code和msg
	 * @param int $code
	 * @param string|null $msg
	 * @return static
	 */
	public function setCodeAndMsg( int $code, string $msg = null ):static {
		// 设置$code
		$this->setCode( $code );
		// 设置$msg
		if( $msg === null ){
			$this->setMsg( com\Lib\Err\Code::getUserText( $this->code ) );
		}else if( str_contains( $msg, '{msg}' ) ){
			$newStatusStr = str_replace( '{msg}', com\Lib\Err\Code::getUserText( $this->code ), $msg );
			$this->setMsg( $newStatusStr );
		}else{
			$this->setMsg( $msg );
		}
		//
		return $this;
	}

	/**
	 * 获取data
	 * @return array
	 */
	public function getData():array {
		return $this->data;
	}

	/**
	 * 设置data
	 * @param array $data
	 * @return static
	 */
	public function setData( array $data ):static {
		$this->data = $data;
		//
		return $this;
	}

	/**
	 * 获取extendedData
	 * @return array
	 */
	public function getExtendedData():array {
		return $this->extendedData;
	}

	/**
	 * 设置extendedData
	 * @param array $extendedData
	 * @return static
	 */
	public function setExtendedData( array $extendedData ):static {
		$this->extendedData = $extendedData;
		//
		return $this;
	}

	/**
	 * 追加extendedData
	 * @param array $extendedData
	 * @return static
	 */
	public function addExtendedData( array $extendedData ):static {
		$this->extendedData = com\Lib\Fun\Array_::arrayMerges( $this->extendedData, $extendedData );
		//
		return $this;
	}

	/**
	 * 快捷->通用
	 * @param int $code 状态
	 * @param string|null $msg 状态说明(自动替换“{msg}”为状态码说明)
	 * @param array $data api数据
	 * @return static
	 */
	public function ofCommon( int $code, string $msg = null, array $data = [] ):static {
		if( $msg === null ){
			$this->setCodeAndMsg( $code );
		}else{
			$this->setCodeAndMsg( $code, $msg );
		}
		$this->setData( $data );
		//
		return $this;
	}

	/**
	 * 快捷->成功
	 * @param array $data
	 * @return static
	 */
	public function ofSuccess( array $data = [] ):static {
		return $this->ofCommon( 1, '', $data );
	}

	/**
	 * 格式化为驼峰命名
	 * @return static
	 */
	public function toParseName():static {
		$this->setData( com\Lib\Fun\Array_::keyNameToParseNames( $this->getData(), 1, false ) );
		return $this;
	}

	/**
	 * 快捷->错误
	 * @param int $code 状态。[0][默认]
	 * @param string|null $msg 状态说明
	 * @param array $data api数据
	 * @return static
	 */
	public function ofError( int $code = 0, string $msg = null, array $data = [] ):static {
		return $this->ofCommon( $code, $msg, $data );
	}

	// ===============================
	//
	//
	// 下面为静态方法
	//
	//
	// ===============================

	/**
	 * @return static
	 */
	public static function makeOfNew():static {
	    return self::make();
	}

	/**
	 * 快捷实例化->通用
	 * @param int $code 状态
	 * @param string|null $msg 状态说明
	 * @param array $data api数据
	 * @return static
	 */
	public static function instanceOfCommon( int $code, string $msg = null, array $data = [] ):static {
		$apiResponse = new static();
		//
		$apiResponse->setCodeAndMsg( $code, $msg );
		$apiResponse->setData( $data );
		//
		return $apiResponse;
	}

	/**
	 * 快捷实例化->成功
	 * @param array $data api数据
	 * @return static
	 */
	public static function instanceOfSuccess( array $data = [] ):static {
		return self::instanceOfCommon( 1, '', $data );
	}

	/**
	 * 快捷实例化->错误
	 * @param int $code 状态。[0][默认]
	 * @param string|null $msg 状态说明
	 * @param array $data api数据
	 * @return static
	 */
	public static function instanceOfError( int $code = 0, string $msg = null, array $data = [] ):static {
		return self::instanceOfCommon( $code, $msg, $data );
	}

	/**
	 * 构建api-array标准格式
	 * @param array $param 参数数组 <br />
	 * ················· [可空](int)	$param['code']	说明：api处理结果。[<=0]处理失败，并返回错误代码 [1][默认]处理成功	<br />
	 * ················· [可空](str)	$param['msg']	说明：api处理结果说明	<br />
	 * ················· [可空](str)	$param['data']	说明：api数据	<br />
	 * ················· [可空/多选_A/必须](unknown_type)	$param['AAAAA']	说明：AAAAA	<br />
	 * @return array api格式的数组
	 */
	protected static function buildArray( array $param = [] ):array {
		return [
			'code' => $param['code'] ?? com\Lib\Api::$varApiCode_Error,
			'msg' => $param['msg'] ?? '',
			// 'data' => array_key_exists( 'data', $param ) ? $param['data'] : [],
			'data' => $param['data'] ?? null,
		];

	}


	/**
	 * 构建api-array（自定义）
	 * @param array $param 参数数组 <br />
	 * ················· [可空](int)	$param['code']	说明：api处理结果。[<=0]处理失败，并返回错误代码 [1][默认]处理成功	<br />
	 * ················· [可空](str)	$param['msg']	说明：api处理结果说明	<br />
	 * ················· [可空](str)	$param['data']	说明：api数据	<br />
	 * ················· [可空/多选_A/必须](unknown_type)	$param['AAAAA']	说明：AAAAA	<br />
	 * @return com\Lib\Api\Response\TypeObj 响应数据类型转换对象
	 */
	public static function build( array $param = [] ):com\Lib\Api\Response\TypeObj {
		$responseArray = self::buildArray( $param );
		return self::toTypeObj( $responseArray );
	}

	/**
	 * 构建api-array标准格式
	 * @param int $code
	 * @param string $msg
	 * @param array|null $data
	 * @param array $extendedData 扩展数据
	 * @return com\Lib\Api\Response\TypeObj 响应数据类型转换对象
	 */
	public static function common( int $code = 0, string $msg = '', ?array $data = [], array $extendedData = [] ):com\Lib\Api\Response\TypeObj {
		$responseArray = self::buildArray( [
			'code' => $code,
			'msg' => $msg,
			'data' => $data,
		] );
		//
		if( ! empty( $extendedData ) ){
			$responseArray = com\Lib\Fun\Array_::arrayMerges( $responseArray, $extendedData );
		}
		//
		return self::toTypeObj( $responseArray );
	}

	/**
	 * 构建api-array标准格式->API执行成功(通用)
	 * @param array $data 其他返回数据
	 * @return com\Lib\Api\Response\TypeObj 响应数据类型转换对象
	 */
	public static function success( array $data = [] ):com\Lib\Api\Response\TypeObj {
		$responseArray = self::buildArray( [
			'code' => com\Lib\Api::$varApiCode_Success,
			'data' => $data,
		] );
		return self::toTypeObj( $responseArray );
	}

	/**
	 * 构建api-array标准格式->API执行失败
	 * @param string $msg 错误结果说明
	 * @param array $param 参数数组 <br />
	 * ················· [可空](str)	$param['msg']	说明：api处理结果说明	<br />
	 * ················· [可空](str)	$param['data']	说明：api返回数据	<br />
	 * ················· [可空/多选_A/必须](unknown_type)	$param['AAAAA']	说明：AAAAA	<br />
	 * @return com\Lib\Api\Response\TypeObj 响应数据类型转换对象
	 *@see $this->sendReply()的$param参数
	 */
	public static function error( string $msg = '', array $param = [] ):com\Lib\Api\Response\TypeObj {
		// ...
		$param['data'] = $param['data'] ?? [];
		//
		$buildReplyParam = com\Lib\Fun\Array_::arrayMerges( $param, [
			'code' => com\Lib\Api::$varApiCode_Error,
			'msg' => $msg,
		] );
		//
		$responseArray = self::buildArray( $buildReplyParam );
		//
		return self::toTypeObj( $responseArray );
	}

	/**
	 * 封装到type对象
	 * @param array $responseArray 响应数据
	 * @return Response\TypeObj
	 */
	private static function toTypeObj( array $responseArray = [] ):Response\TypeObj {
		return new com\Lib\Api\Response\TypeObj( $responseArray );
	}

}
